package com.cdn.auth.context;

import com.cdn.auth.config.CAuthProperties;
import com.cdn.auth.consts.CAuthConst;
import com.cdn.auth.user.UserDetails;
import com.cdn.auth.user.UserInfo;
import com.cdn.auth.util.UUIDUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * 蔡定努
 * 2024/06/28 21:14
 */
public class TokenManager {

    @Resource
    private CAuthProperties cAuthProperties;
    @Resource
    private RedisTemplate<String, UserInfo> redisTemplate;
    @Resource
    private HttpServletRequest request;


    /**
     * @author 蔡定努
     */
    public String createToken(UserDetails userDetails) {
        String token = UUIDUtil.getUuid();
        long expireAt = System.currentTimeMillis() + cAuthProperties.getExpireTime();

        UserInfo info = new UserInfo(userDetails, expireAt);
        redisTemplate.opsForValue().set(getTokenKey(token), info, cAuthProperties.getExpireTime(), TimeUnit.SECONDS);
        UserContext.set(info);
        return token;
    }


    public boolean removeToken() {
        String token = getToken();
        if (!StringUtils.hasText(token)) {
            return true;
        }
        redisTemplate.delete(getTokenKey(token));
        UserContext.remove();
        return true;
    }

    /**
     * @author 蔡定努
     */
    public boolean isValidToken(HttpServletRequest request) {
        String token = getToken();
        if (!StringUtils.hasText(token)) {
            return false;
        }
        UserInfo userInfo = redisTemplate.opsForValue().get(getTokenKey(token));
        boolean b = userInfo != null;
        if (b) {
            UserContext.set(userInfo);
        }
        return b;
    }


    /**
     * @author 蔡定努
     */
    public void refreshToken() {
        String token = getToken();
        UserInfo userInfo = UserContext.get();
        Long expireAt = userInfo.getExpireAt();
        long currentTimeMillis = System.currentTimeMillis();
        long l = expireAt - currentTimeMillis;
        // 距离过期小于15分钟，刷新
        if (l >0 && l <= cAuthProperties.getTimeInterval()) {
            userInfo.setExpireAt(currentTimeMillis + cAuthProperties.getExpireTime());
            redisTemplate.opsForValue().set(getTokenKey(token), userInfo, cAuthProperties.getExpireTime(), TimeUnit.SECONDS);
            UserContext.set(userInfo);
        }
    }

    /**
     * @author 蔡定努
     */
    public String getToken() {
        String headerKey = cAuthProperties.getHeaderKey();
        return request.getHeader(headerKey);
    }

    private String getTokenKey(String uuid) {
        return CAuthConst.USER_INFO_KEY + uuid;
    }


}
